;;;; -*- Emacs-Lisp -*-
;; __________
;; ___  ____/______ _________ ______________
;; __  __/  __  __ `__ \  __ `/  ___/_  ___/
;; _  /___  _  / / / / / /_/ // /__ _(__  )
;; /_____/  /_/ /_/ /_/\__,_/ \___/ /____/
;;
;; Emacs - Gnu Emacs Operating System - by sern
;;
;;            Author: sern
;;           Version: 1.0
;;      LastModified: Jan 02 11 17:43:31
;;             Email: sern.cheung@gmail.com
;;

;;;; ,----------
;;  / Setup extend lisp add-ons.
;;  `--------------------
;;
(defconst sec-rt-root-path
  (getenv "EMACS_CONF_ROOT")
  "extra emacs's runtime path")

(defconst sec-rt-site-lisp-path
  (concat
   sec-rt-root-path
   "/site-lisp/"))

(defconst sec-rt-site-init-path
  (concat
   sec-rt-root-path
   "/site-init"))

;;;; ,----------
;;  / Start self bootstrap.
;;  `--------------------
;;
;; Fix emacs load path for the features be load soon.
(defun sec-add-sub-to-load-path (path)
  "*Add PATH and it's sub directories to `load-path'"
  (interactive)
  (let ((subs (directory-files path)))
    (dolist (sub subs)
      (unless (member sub '("." ".." ".svn"))
        (setq sub (concat path sub))
        (when (file-directory-p sub)
          (add-to-list 'load-path sub))))))

(mapc (lambda (path)
        (sec-add-sub-to-load-path path))
      (list
       sec-rt-site-lisp-path))

;;;; ,----------
;;  / Emacs site define
;;  `--------------------
;;
(defgroup sern-emacs nil
  "*Group for sern's emacs config")

(defconst sec-emacs-cache-path "~/.emacs.cache/"
  "*Directory for cache of emacs.")

(unless (file-exists-p sec-emacs-cache-path)
  (make-directory sec-emacs-cache-path t))

(defconst sec-code-common-hooks
  '(emacs-lisp-mode-hook
    c-mode-common-hook
    makefile-mode-hook)
  "*Code hooks for enables features.")

(defcustom sec-newline-hook nil
  "*Hook for `sec-smart-newline-and-indent'."
  :type 'hook
  :group 'sern-emacs)
(make-variable-buffer-local 'sec-newline-hook)

;;;; ,----------
;;  / Advanced lisp function setup
;;  `--------------------
;;
(defun sec-reload-emacs-config ()
  "*Reload emacs config script."
  (interactive)
  (load-file "~/.emacs"))

(defun sec-smart-newline-and-indent ()
  "*Kill whitespace-only line, then `newline-and-indent'."
  (interactive)
  (when (and (eolp)
             (save-excursion
               (re-search-backward "^[ \t]+$" (line-beginning-position) t)))
    (kill-line 0))
  (indent-for-tab-command)
  (newline-and-indent)
  (run-hooks 'sec-newline-hook))

(defun sec-smart-backspace ()
  "*Delete the preceding character or whitespace.
If point is at the end of a whitespace-only line, then all preceding whitespace
is consumed besides `/n', otherwise, delete the previous character only."
  (interactive)
  (if (and (eolp)
	   (save-excursion
	     (re-search-backward "^[ \t]+$" (line-beginning-position) t)))
      (kill-line 0)
    (delete-backward-char 1)))

(defmacro sec-kill-buffer-list (buffer-list)
  "*Kill buffers in LIST.
but does nothing if the buffer is visiting a real file and the file is modified."
  `(dolist (buffer ,buffer-list)
     (let ((buf (get-buffer buffer)))
       (when (and buf (or (not (buffer-file-name buf))
			  (not (buffer-modified-p buf))))
	 (ignore-errors (kill-buffer buf))))))

(defun sec-kill-all-buffer ()
  "*Kill all buffers.
but does nothing if the buffer is visiting a real file and the file is modified."
  (interactive)
  (sec-kill-buffer-list (buffer-list)))

(defun sec-kill-other-buffer ()
  "*Kil all buffers except the current one.
but does nothing if the buffer is visiting a real file and the file is modified."
  (interactive)
  (sec-kill-buffer-list (delq (current-buffer) (buffer-list))))

(defmacro sec-require-maybe (feature &optional file)
  "*Try to require FEATURE, but don't signal an error if `require' fails."
  `(let ((require-result (require ,feature ,file 'noerror)))
     (with-current-buffer (get-buffer-create "*Startup Log*")
       (let* ((startup-log-format-string-prefix "%-20s--------[")
              (startup-log-format-string-postfix "%s")
              (startup-status (if require-result "LOADED" "FAILED"))
              (startup-status-face `(face (:foreground
                                           ,(if require-result "green" "red")))))
         (insert (format startup-log-format-string-prefix ,feature))
         (let ((start-pos (point)))
           (insert (format startup-log-format-string-postfix startup-status))
           (add-text-properties start-pos (point) startup-status-face)
           (insert "]\n"))))
     require-result))

;;;; ,----------
;;  / Personal information
;;  `--------------------
;;
(setq user-full-name "sern"
      user-mail-address "sern.cheung@gmail.com")

;;;; ,----------
;;  / Multi-lingual environment for using `UTF-8'
;;  `--------------------
;;
;; This sets the coding system priority and the default input method
;; and sometimes other things.
(set-language-environment 'UTF-8)
(set-locale-environment "UTF-8")

;;;; ,----------
;;  / Emacs initialzation customization
;;  `--------------------
;;
;; Cleanup the needless appearance units.
(menu-bar-mode -1)
(when (and (fboundp 'tool-bar-mode)
	   (fboundp 'scroll-bar-mode))
  (tool-bar-mode -1)
  (scroll-bar-mode -1))

;; Get rid of startup screen and open the scratch buffer with none in it.
(setq inhibit-startup-screen t
      initial-scratch-message nil)

;; no bell and flash the frame.
(setq ring-bell-function 'ignore)

;; Reduce the respond keystroke.
(fset 'yes-or-no-p 'y-or-n-p)

;; Don't ask me when kill a buffer which has a running process.
(setq kill-buffer-query-functions (delq 'process-kill-buffer-query-function kill-buffer-query-functions))

;; Enable some function.
(put 'downcase-region 'disabled nil)

;; No delay for keystrokes in echo erea.
(setq echo-keystrokes -1)

;; Use text-mode as the default one.
(setq-default major-mode 'text-mode)

;; Column beyond which automatic line-wrapping should happen.
(setq-default fill-column 80)
(auto-fill-mode -1)

;; Truncate long lines for current window instead of wrap it
(setq-default truncate-partial-width-windows nil
	      truncate-lines t)
(set-display-table-slot standard-display-table 'truncation ?$)

;; Show match paren instead of jump to it.
(show-paren-mode t)
(setq show-paren-delay 0)

;; Make the buffer read-only if which is loaded from a file.
(add-hook 'find-file-hook (lambda () (toggle-read-only t)))

;; Don't generate auto-save file, but enable backup function.
(let ((save-cache (concat sec-emacs-cache-path "save-file.cache/")))
  (unless (file-exists-p save-cache)
    (make-directory save-cache t))
  (setq auto-save-default nil
	make-backup-files t
	vc-make-backup-files nil
	backup-directory-alist (list (cons "." save-cache))
	delete-old-versions t
	kept-new-versions 2
	kept-old-versions 2
	version-control t))

;;;; ,----------
;;  / Emacs daemon
;;  `--------------------
;;
;; Define the style of frame in X even if running emacs as a daemon.
(setq default-frame-alist
      (append
       '((font . "Monaco-10"))
       default-frame-alist))
(setq initial-frame-alist default-frame-alist)

(defun sec-toggle-full-screen ()
  "*Toggle full screen mode"
  (interactive)
  (x-send-client-message
   nil 0 nil "_NET_WM_STATE" 32
   '(2 "_NET_WM_STATE_FULLSCREEN" 0)))

(defun sec-frame-setting ()
  "*Custom frame's configuration."
  (when window-system
    (blink-cursor-mode -1)
    (setq-default cursor-type 'hbar)
    (setq-default mouse-yank-at-point t)
    (setq-default x-select-enable-clipboard t)))

(if (and (fboundp 'daemonp) (daemonp))
    (progn
      (cd (getenv "HOME"))
      (add-hook 'after-make-frame-functions
		(lambda (frame)
		  (with-selected-frame frame
		    (sec-frame-setting)))))
  (sec-frame-setting))

;;;; ,----------
;;  / Mode line
;;  `--------------------
;;
;; Show date and time in status line.
(setq display-time-24hr-format t
      display-time-day-and-date nil
      display-time-load-average-threshold 20)
(display-time-mode t)

;; Show column number in status line.
(setq column-number-mode t)

;; Function for get lines of current buffer.
(defun sec-get-lines-for-mode-line ()
  (let ((lines (count-lines (point-min) (point-max))))
    (format "%dL " lines)))

;; Custom mode line format.
(setq-default
 mode-line-position
 `((:eval (sec-get-lines-for-mode-line))
   (:propertize "%p ")
   (:eval
    (if line-number-mode
	(if column-number-mode
	    (propertize "(%l,%c)")
	  (propertize " L%l"))
      (if column-number-mode
	  (propertize " C%c"))))))

(setq-default
 mode-line-buffer-identification
 `((:eval
    (propertize
     (if (buffer-file-name (current-buffer))
	 "%12f"
       "%12b")
     'face 'mode-line-buffer-id))))

(let* ((help-echo
        "mouse-1: Select (drag to resize)\n\
mouse-2: Make current window occupy the whole frame\n\
mouse-3: Remove current window from display")
       (recursive-edit-help-echo "Recursive edit, type C-M-c to get out")
       (standard-mode-line-modes
        (list
         " "
         (propertize "%[" 'help-echo recursive-edit-help-echo)
         (propertize "(" 'help-echo help-echo)
         `(:propertize ("" mode-name)
                       help-echo "Major mode\n\
mouse-1: Display major mode menu\n\
mouse-2: Show help for major mode\n\
mouse-3: Toggle minor modes"
                       mouse-face mode-line-highlight
                       local-map ,mode-line-major-mode-keymap)
         '("" mode-line-process)
         `(:propertize ("" minor-mode-alist)
                       mouse-face mode-line-highlight
                       help-echo "Minor mode\n\
mouse-1: Display minor mode menu\n\
mouse-2: Show help for minor mode\n\
mouse-3: Toggle minor modes"
                       local-map ,mode-line-minor-mode-keymap)
         (propertize "%n" 'help-echo "mouse-2: Remove narrowing from the current buffer"
                     'mouse-face 'mode-line-highlight
                     'local-map (make-mode-line-mouse-map
                                 'mouse-1 #'mode-line-widen))
         (propertize ")" 'help-echo help-echo)
         (propertize "%]" 'help-echo recursive-edit-help-echo))))
  (setq-default mode-line-modes standard-mode-line-modes)
  (setq-default mode-line-format
		`("%e%t"
		  mode-line-mule-info
		  mode-line-client
		  mode-line-modified
		  mode-line-remote
		  mode-line-frame-identification
		  mode-line-buffer-identification
		  ,(propertize " ")
		  mode-line-position
		  (vc-mode vc-mode)
		  mode-line-modes
		  (which-func-mode (" " which-func-format))
		  (global-mode-string (" " global-mode-string))
		  ,(propertize "-%-"))))

;; Custom titile of frame.
(setq frame-title-format
      '((:eval
	 (let ((login-name (getenv-internal "LOGNAME")))
	   (if login-name (concat login-name "@") "")))
	(:eval (system-name))
	" : "
	(:eval (or (buffer-file-name) (buffer-name)))))

;;;; ,----------
;;  / Color theme
;;  `--------------------
;;
(defconst sec-color-theme-frame-alist
  '(
    (background-color . "#121212")
    (background-mode  . dark)
    (border-color     . "Black")
    (cursor-color     . "#eeeeee")
    (foreground-color . "#eeeeee")
    (mouse-color      . "Sienna1")))

(defun sec-alist-reduce (old-list)
  (let (new-list)
    (dolist (elem old-list)
      (when (not (assq (car elem) new-list))
	(setq new-list (cons elem new-list))))
    new-list))

(let ((params sec-color-theme-frame-alist)
      (frames (frame-list)))
  (setq default-frame-alist
	(sec-alist-reduce
	 (append params default-frame-alist))
	minibuffer-frame-alist
	(sec-alist-reduce
	 (append params minibuffer-frame-alist)))
  (dolist (frame frames)
    (let ((params (if (eq 'only (cdr (assq 'minibuffer (frame-parameters frame))))
		      minibuffer-frame-alist
		    default-frame-alist)))
      (condition-case var
	  (modify-frame-parameters frame params)
	(error (message "Error using params %S: %S" params var))))))

(custom-set-faces
 ;; Default color attribute.
 '(default ((t (:inherit nil
			 :stipple nil
			 :background "#232323"
			 :foreground "#eeeeee"
			 :inverse-video nil
			 :box nil
			 :strike-through nil
			 :overline nil
			 :underline nil
			 :slant normal
			 :weight normal
			 :height 110
			 :width normal
			 :foundry nil
			 :family "Monaco"
			 ))))
 ;; Basic
 '(bold ((t (:weight bold))))
 '(italic ((t (:slant italic))))
 '(bold-italic ((t (:slant italic :weight bold))))

 ;; Buffer
 '(buffer-menu-buffer ((t (:bold t))))
 '(buffer-tab ((t (:background "#0c1021" :foreground "#f8f8f8"))))

 ;; Misc
 '(menu ((t (nil))))
 '(scroll-bar ((t (nil))))
 '(tool-bar ((t (nil))))
 '(button ((t (:underline t))))
 '(fringe ((t (:background "Grey10"))))
 '(header-line ((t (:inherit mode-line :underline t))))
 '(border ((t (:background "Black"))))
 '(border-glyph ((t (nil))))
 '(help-argument-name
   ((t (:blod t :foreground "Green" :italic t :bold t))))
 '(highlight
   ((((class color) (min-colors 88))
     (:background "#222222"))
    (t (:inverse-video t))))
 '(lazy-highlight ((t (:background "PaleTurquoise4"))))
 '(isearch
   ((((class color) (min-colors 88))
     (:background "#fce94f" :foreground "#232323"))
    (t
     (:background "Yellow" :foreground "Black"))))
 '(isearch-fail
   ((((class color) (min-colors 88))
     (:background "#ff2f6a" :foreground "YellowGreen" :bold t))
    (t (:background "Red" :foreground "Yellow" :bold t))))
 '(left-margin ((t (nil))))
 '(link
   ((((class color) (min-colors 88))
     (:foreground "#06989a" :underline t :bold t))
    (t (:foreground "Blue" :underline t :bold t))))
 '(link-visited
   ((((class color) (min-colors 88))
     (:foreground "Violet" :underline t :italic t))
    (t (:foreground "Magenta" :underline t :italic t))))
 '(linum
   ((((class color) (min-colors 88))
     (:background "#1c1c1c" :foreground "#bcbcbc" :bold t))
    (t (:foreground "Cyan" :bold t))))
 '(hl-line ((t (:underline t))))
 '(secondary-selection ((t (:background "#bbbbbb" :foreground "#eeeeee"))))
 '(match
   ((((class color) (min-colors 88))
     (:background "RoyalBlue3" :foreground "#232323" :bold t))
    (t (:foreground "Blue" :foreground "Black" :bold t))))
 '(next-error ((t (:background "#555753"))))
 '(nobreak-space ((t (:foreground "Cyan" :underline t))))
 '(query-replace
   ((((class color) (min-colors 88))
     (:background "PaleVioletRed2" :foreground "Brown4"))
    (t (:background "Red" :foreground "Black"))))
 '(region
   ((((class color) (min-colors 88))
     (:background "#555753"))
    (t (:background "Blue" :foreground "White"))))
 '(region-invert
   ((((class color) (min-colors 88))
     (:foreground "#555753"))
    (t (:foreground "Blue"))))
 '(shadow
   ((((class color) (min-colors 88))
     (:foreground "Grey70"))
    (t (nil))))
 '(show-paren-match
   ((((class color) (min-colors 88))
     (:background "#bb66ff" :foreground "#eeeeee" :bold t))
    (t (:background "Magenta" :foreground "White" :bold t))))
 '(show-paren-mismatch
   ((((class color) (min-colors 88))
     (:background "#ff2f6a" :foreground "#232323" :bold t))
    (t (:background "Red" :foreground "White" :bold t))))

 ;; Minibuffer
 '(minibuffer-prompt
   ((((class color) (min-colors 88))
     (:foreground "#fce94f" :bold t))
    (t (:foreground "Yellow" :bold t))))

 ;; Mode-line
 '(mode-line
   ((((class color) (min-colors 88))
     (:background "#080808" :foreground "Gray60"
		  :box (:line-width -1 :color "Gray50")
		  :weight semi-bold))
    (t (:background "White" :foreground "Black"))))
 '(mode-line-buffer-id
   ((((class color) (min-colors 88))
     (:background "#000000" :foreground "#009cff" :bold t))
    (t (:background "Black" :foreground "Blue" :bold t))))
 '(mode-line-emphasis ((t (:bold t))))
 '(mode-line-highlight ((t (:background "#bb66ff"))))
 '(mode-line-inactive
   ((((class color) (min-colors 88))
     (:background "#080808" :foreground "Gray70"
		  :box (:line-width -1 :color "Gray40")))
    (t (:background "White" :foreground "Black"))))
 '(modeline-mousable ((t (:background "Gray10" :foreground "White"))))
 '(modeline-mousable-minor-mode
   ((t (:background "Gray10" :foreground "White"))))
 '(which-func
   ((((class color) (min-colors 88))
     (:background "#000000" :foreground "#9e91ff"))
    (t (:background "White" :foreground "Blue"))))

 ;; Calendar
 '(cal-china-x-general-holiday-face ((t (:background "Green"))))
 '(cal-china-x-important-holiday-face ((t (:background "Red"))))
 '(calendar-today
   ((((class color) (min-colors 88))
     (:background "Black" :foreground "#ff9900" :underline t))
    (t (:background "White", :foreground "Yellow"))))

 ;; Completion
 '(completions-annotations ((t (:foreground "Cyan1"))))
 '(completions-common-part ((t (:inherit default))))
 '(completions-first-difference ((t (:bold t))))

 ;; Dired
 '(dired-directory
   ((((class color) (min-colors 88))
     (:foreground "#9e91ff" :bold t))
    (t (:foreground "Blue" :bold t))))
 '(dired-flagged ((t (:foreground "Pink" :bold t))))
 '(dired-header
   ((((class color) (min-colors 88))
     (:foreground "#bb66ff" :italic t :bold t))
    (t (:foreground "Cyan" :italic t :bold t))))
 '(dired-ignored
   ((((class color) (min-colors 88))
     (:foreground "Grey70"))
    (t (:foreground "White"))))
 '(dired-mark
   ((((class color) (min-colors 88))
     (:foreground "#009cff"))
    (t (:foreground "Cyan"))))
 '(dired-marked
   ((((class color) (min-colors 88))
     (:foreground "#009cff" :bold t))
    (t (:foreground "Cyan" :bold t))))
 '(dired-perm-write ((t (:foreground "#bb66ff" :italic t))))
 '(dired-symlink
   ((((class color) (min-colors 88))
     (:foreground "#bb66ff"))
    (t (:foreground "Magenta"))))
 '(dired-warning
   ((((class color) (min-colors 88))
     (:foreground "#ff2f6a" :bold t))
    (t (:foreground "Red" :bold t))))

 ;; Erc
 '(erc-default-face ((t (nil))))
 '(erc-bold-face ((t (:bold t))))
 '(erc-underline-face ((t (:underline t))))
 '(erc-action-face ((t (:bold t))))
 '(erc-current-nick-face ((t (:foreground "LightSeaGreen" :bold t))))
 '(erc-dangerous-host-face ((t (:foreground "#ff2f6a"))))
 '(erc-error-face ((t (:background "DarkBlue" :foreground "#ff2f6a" :bold t))))
 '(erc-fool-face ((t (:foreground "DimGray"))))
 '(erc-input-face ((t (:foreground "#009cff"))))
 '(erc-inverse-face ((t (:background "DarkGreen" :foreground "Black" :bold t))))
 '(erc-keyword-face ((t (:foreground "#ff9900" :bold t))))
 '(erc-nick-default-face ((t (:weight :bold t))))
 '(erc-nick-msg-face ((t (:foreground "#ff6100" :bold t))))
 '(erc-notice-face ((t (:foreground "#bb66ff"))))
 '(erc-pal-face ((t (:foreground "MediumAquaMarine" :bold t))))
 '(erc-prompt-face ((t (:background "Black" :foreground "#ff9900" :bold t))))
 '(erc-timestamp-face ((t (:foreground "#96ff00"))))

 ;; Font-Lock
 '(font-lock-builtin-face
   ((((class color) (min-colors 88))
     (:foreground "#fce94f"))
    (t (:foreground "Yellow"))))
 '(font-lock-comment-delimiter-face
   ((((class color) (min-colors 88))
     (:foreground "#bb66ff" :italic t :bold t))
    (t (:foreground "Magenta" :italic t :bold t))))
 '(font-lock-comment-face ((t (:inherit font-lock-comment-delimiter-face))))
 '(font-lock-doc-string-face ((t (:inherit font-lock-comment-face))))
 '(font-lock-doc-face ((t (:inherit font-lock-comment-face))))
 '(font-lock-constant-face
   ((((class color) (min-colors 88))
     (:foreground "#fce94f"))
    (t (:foreground "Yellow"))))
 '(font-lock-function-name-face
   ((((class color) (min-colors 88))
     (:foreground "#ffffff"))
    (t (:foreground "White"))))
 '(font-lock-keyword-face
   ((((class color) (min-colors 88))
     (:foreground "#ff9900" :bold t))
    (t (:foreground "Yellow" :bold t))))
 '(font-lock-negation-char-face ((t (nil))))
 '(font-lock-preprocessor-face
   ((((class color) (min-colors 88))
     (:foreground "#00d8ff" :bold t))
    (t (:foreground "Cyan" :bold t))))
 '(font-lock-reference-face ((t (:foreground "SlateBlue"))))
 '(font-lock-regexp-grouping-backslash
   ((((class color) (min-colors 88))
     (:foreground "#bbbbbb"))
    (t (:foreground "Red"))))
 '(font-lock-regexp-grouping-construct
   ((((class color) (min-colors 88))
     (:foreground "#ff44cc"))
    (t (:foreground "Red"))))
 '(font-lock-string-face
   ((((class color) (min-colors 88))
     (:foreground "#00ff5f"))
    (t (:foreground "Green"))))
 '(font-lock-type-face
   ((((class color) (min-colors 88))
     (:foreground "#00afff"))
    (t (:foreground "Cyan"))))
 '(font-lock-variable-name-face
   ((((class color) (min-colors 88))
     (:foreground "#ffffff"))
    (t (:foreground "White"))))
 '(font-lock-warning-face
   ((((class color) (min-colors 88))
     (:foreground "#ff2f6a" :bold t))
    (t (:foreground "Red" :bold t))))

 ;; Makefile
 '(makefile-shell
   ((((class color) (min-colors 88))
     (:foreground "Wheat"))
    (t (:foreground "Yellow"))))
 '(makefile-space ((t (:background "#ff79d9"))))
 '(makefile-targets ((t (:foreground "#009cff" :weight semi-bold))))
 )

;;;; ,----------
;;  / Shell mode
;;  `--------------------
;;
;; Turn on this for correct color of shell in emacs.
(ansi-color-for-comint-mode-on)

;;;; ,----------
;;  / Term mode
;;  `--------------------
;;
;;  To use common emacs key-binding in term-mode, add a prefix
;;  `C-c' or `C-x' before it.
(add-hook 'term-mode-hook
	  (lambda ()
	    (define-key term-raw-map (kbd "C-c") 'term-send-raw)
	    (define-key term-raw-map (kbd "M-x") 'execute-extended-command)
	    (term-set-escape-char ?\C-x)))

;; Add some advice to `term' and `shell' mode.
(defadvice term (before hack-advice activate)
  (switch-to-buffer (get-buffer-create "*terminal*"))
  (animate-string "-- Hack and glory await! --" 0 0)
  (insert "\n\n"))

(defadvice shell (before hack-advice activate)
  (switch-to-buffer (get-buffer-create "*shell*"))
  (animate-string "-- Hack and glory await! --" 0 0)
  (insert "\n\n"))

;;;; ,----------
;;  / Eshell mode
;;  `--------------------
;;
;; The banner message to be displayed when Eshell is loaded.
(setq eshell-banner-message "\n\n");

;; Function that returns the Eshell prompt string.
(setq eshell-prompt-function
      (lambda ()
	(concat
	 "["
	 (let ((pwd (eshell/pwd)))
	   (if (string= pwd (getenv "HOME"))
	       "~" pwd))
	 (if (= (user-uid) 0)
	     " #" " $")
	 "] ")))

;; Regexp which fully matches eshell prompt.
(setq eshell-prompt-regexp "^\\[.* [#$]\\] ")

(let ((eshell-alias-dir (concat sec-rt-root-path "eshell/")))
  (unless (file-exists-p eshell-alias-dir)
    (make-directory eshell-alias-dir t))
  (setq eshell-directory-name eshell-alias-dir)
  (setq eshell-aliases-file
	(concat
         eshell-alias-dir
         "alias"))
  (setq eshell-last-dir-ring-file-name
	(concat
         eshell-alias-dir
         "lastdir"))
  (setq eshell-history-file-name
	(concat
         eshell-alias-dir
         "histroy"))
  )

;; Avoid completion cycling in shell when press `TAB'.
(setq eshell-cmpl-cycle-completions nil
      eshell-cmpl-restore-window-delay 0)

;; Alias some shell command to emacs function.
(defalias 'em 'find-file)
(defalias 'ec 'find-file)
(defalias 'ex 'find-file)

;; Define key bindings that like normal shell.
(add-hook 'eshell-mode-hook
	  (lambda ()
	    (animate-string "-- Hacks and glory await! --" 0 0)
	    (eshell-next-prompt 2)
	    (define-key eshell-mode-map (kbd "C-u")  'eshell-kill-input)
	    (define-key eshell-mode-map (kbd "C-n")  'eshell-next-matching-input-from-input)
	    (define-key eshell-mode-map (kbd "C-p")  'eshell-previous-matching-input-from-input)
	    (define-key eshell-mode-map (kbd "C-\\") 'eshell-quit-process)
	    (define-key eshell-mode-map (kbd "C-c")  'eshell-interrupt-process)
	    (define-key eshell-mode-map (kbd "C-d")  'sec-eshell-exit-or-delete-char)))

(defun sec-eshell-exit-or-delete-char ()
  "*Exit eshell when no command after prompt, otherwise delete a char."
  (interactive)
  (if (and (eolp)
	   (save-excursion
	     (re-search-backward
              (concat eshell-prompt-regexp "$")
              (line-beginning-position)
              t)))
      (progn
	(insert "exit")
	(eshell-send-input))
    (delete-char 1)))

(defmacro sec-fetch-shell (suff proc)
  "*Fetch shell buffer, then rename it so that we can have mulit-shell."
  `(let* ((default-suffix "suff")
	  (shell-buffer-name
	   (concat "*"
		   ,proc
		   "."
		   (if (string= "" suff)
		       default-suffix
		     suff)
		   "*")))
     (if (get-buffer shell-buffer-name)
	 (switch-to-buffer shell-buffer-name)
       (progn
	 (cond ((string= ,proc "shell")
		;; invoke an inferior shell, with I/O through buffer.
		(shell))
	       ((string= ,proc "eshell")
		;; create an interactive Eshell buffer.
		(eshell))
	       ((string= ,proc "term")
		;; start a terminal-emulator in a new buffer.
	        (term "/bin/bash")))
	 (rename-buffer shell-buffer-name t)))))

(defun sec-fetch-eshell (suff)
  "*Fetch the eshell buffer."
  (interactive "ssuff for this shell: ")
  (sec-fetch-shell suff "eshell"))

(defun sec-fetch-term (suff)
  "*Fetch the term buffer."
  (interactive "ssuff for this shell: ")
  (sec-fetch-shell suff "term"))

(defun sec-kill-buffer-when-shell-cmd-exit ()
  "*Close buffer automatically when process in this buffer exited."
  (let ((process (ignore-errors (get-buffer-process (current-buffer)))))
    (when process
      (set-process-sentinel process
                            (lambda (proc state)
                              (when (string-match "\\(finished\\|exited\\)" state)
                                (run-at-time 0.5 nil 'kill-buffer (current-buffer))))))))
(dolist (hook '(shell-mode-hook term-mode-hook))
  (add-hook hook 'sec-kill-buffer-when-shell-cmd-exit))

;;;; ,----------
;;  / Linum
;;  `--------------------
;;
(setq-default linum-format
	      (lambda (line)
		(let ((w (length (number-to-string
				  (count-lines (point-min) (point-max))))))
		  (propertize
		   (format (concat (format "%%%dd" w) " | ") line)
		   'face 'linum))))

(dolist (hook sec-code-common-hooks)
  (add-hook hook (lambda () (linum-mode t))))

;;;; ,----------
;;  / Highlight current line
;;  `--------------------
;;
(dolist (hook sec-code-common-hooks)
  (add-hook hook (lambda () (hl-line-mode t))))

;;; ,----------
;;  / Font lock
;;  `--------------------
;;
;; Enable font-lock mode in every possible buffer.
(global-font-lock-mode t)

(defface sec-font-lock-whitespace-face
  '((t (:background "red1")))
  "*Face used to visualize extra whitespace."
  :group 'sern-emacs)

(defface sec-font-lock-long-line-face
  '((t (:background "#444444")))
  "*Face used to visualize long lines."
  :group 'sern-emacs)

(defun sec-unix-code-add-keywords ()
  "*Add some keywords to specified mode."
  (interactive)
  (font-lock-add-keywords
   nil
   '(("\\<\\(FIXME\\|TODO\\|Todo\\|XXX\\|HACK\\)\\>" 1 font-lock-warning-face t)
     ("\\(\\(\t\\| \\)+\\)$" 1 'sec-font-lock-whitespace-face t)
     ("^\\(?:[^\t\n]\\{8\\}\\|[^\t\n]\\{,7\\}\t\\)\\{10\\}\\(\\(.\\).*\\)$" 1 'sec-font-lock-long-line-face append))))

;;; ,----------
;;  / Coding preferences
;;  `--------------------
;;
;; Cause emacs to enter c-mode when editing `.h' files.
;; to enter c++-mode, add the comment
;;      `-*- C++ -*-'
;; to the first line of file.
(setq auto-mode-alist (cons '("\\.h$" . c++-mode) auto-mode-alist))

(defconst unix-code-style
  '((c-tab-always-indent . t)
    (c-basic-offset . 8)
    (c-ignore-auto-fill . nil)
    (c-comment-only-line-offset . (0 . 0))
    ;; Controls the insertion of newlines before and after braces.
    (c-hanging-braces-alist . ((substatement-open after before)
                               (brace-list-open)))
    ;; Controls the insertion of newlines before and after colons.
    (c-hanging-colons-alist . ((member-init-intro before)
                               (inher-intro)
                               (case-label after)
                               (label after)
                               (access-label after)))
    ;; List of various C/C++/ObjC constructs to `clean up'.
    (c-cleanup-list . (scope-operator
		       empty-defun-braces
		       defun-close-semi))
    ;; Association list of syntactic element symbols and indentation offsets.
    (c-offsets-alist . ((inexpr-class . +)
                        (inexpr-statement . +)
                        (lambda-intro-cont . +)
                        (inlambda . c-lineup-inexpr-block)
                        (template-args-cont c-lineup-template-args +)
                        (incomposition . +)
                        (inmodule . +)
                        (innamespace . +)
                        (inextern-lang . +)
                        (composition-close . 0)
                        (module-close . 0)
                        (namespace-close . 0)
                        (extern-lang-close . 0)
                        (composition-open . 0)
                        (module-open . 0)
                        (namespace-open . 0)
                        (extern-lang-open . 0)
                        (objc-method-call-cont c-lineup-ObjC-method-call-colons c-lineup-ObjC-method-call +)
                        (objc-method-args-cont . c-lineup-ObjC-method-args)
                        (objc-method-intro . [0])
                        (friend . 0)
                        (cpp-define-intro c-lineup-cpp-define +)
                        (cpp-macro-cont . +)
                        (cpp-macro . [0])
                        (inclass . +)
                        (stream-op . c-lineup-streamop)
                        (arglist-cont-nonempty c-lineup-gcc-asm-reg c-lineup-arglist)
                        (arglist-cont c-lineup-gcc-asm-reg 0)
                        (comment-intro c-lineup-knr-region-comment c-lineup-comment)
                        (catch-clause . 0)
                        (else-clause . 0)
                        (do-while-closure . 0)
                        (access-label . -)
                        (case-label . 0)
                        (substatement . +)
                        (statement-case-intro . +)
                        (statement . 0)
                        (brace-entry-open . 0)
                        (brace-list-entry . 0)
                        (brace-list-intro . +)
                        (brace-list-close . 0)
                        (block-close . 0)
                        (block-open . 0)
                        (inher-cont . c-lineup-multi-inher)
                        (inher-intro . +)
                        (member-init-cont . c-lineup-multi-inher)
                        (member-init-intro . +)
                        (topmost-intro . 0)
                        (knr-argdecl . 0)
                        (func-decl-cont . +)
                        (inline-close . 0)
                        (class-close . 0)
                        (class-open . 0)
                        (defun-block-intro . +)
                        (defun-close . 0)
                        (defun-open . 0)
                        (c . c-lineup-C-comments)
                        (string . c-lineup-dont-change)
                        (topmost-intro-cont . 0)
                        (brace-list-open . +)
                        (inline-open . 0)
                        (arglist-close . c-lineup-close-paren)
                        (arglist-intro . +)
                        (statement-cont . c-lineup-math)
                        (statement-case-open . +)
                        (label . 0)
                        (substatement-label . 2)
                        (substatement-open . 0)
                        (knr-argdecl-intro . +)
                        (statement-block-intro . +)))
    (c-block-comment-prefix . "")
    (c-echo-syntactic-information-p . nil))
  "*Sern's C Programming Style.")

(defun sec-unix-code-init-hook ()
  "*Key-bindings to add to specified mode."
  ;; Put key-binding in `c-mode-base-map' because c-mode-map, c++-mode-map, and so on, inherit from it.
  (define-key c-mode-base-map (kbd "DEL") 'sec-smart-backspace)
  (define-key c-mode-base-map (kbd "M-/") 'semantic-complete-analyze-inline))

(defun sec-auto-insert-comment-star-hook ()
  "*Insert star '*' if in a multi-line comment."
  (if (save-excursion
	(previous-line 1)
	(end-of-line)
	(and
	 (save-excursion
	   (re-search-backward
	    "^[ \t]*\\(\/\\*\\|\\*[ \t]+.*$\\|\\*$\\)" (line-beginning-position) t))
	 (not (save-excursion
		(re-search-backward "*/$" (line-beginning-position) t)))))
      (progn
	(insert "* ")
	(indent-for-tab-command))))

(defun sec-unix-code-common-hook ()
  "*Customize unix personal coding style."
  (interactive)
  ;; Use `make' repleace the default `make -k'.
  (setq compile-command "make")
  ;; c/c++ basic style.
  ;; (c-set-style "K&R")
  (c-add-style "Sern&Unix" unix-code-style t)
  ;; Tab and indent width, and make sure spaces are used instead of tabs.
  (setq c-basic-offset 8
        tab-width 8
        indent-tabs-mode nil)
  ;; Enable hungry delete action, but not auto-newline.
  (c-toggle-hungry-state -1)
  (c-toggle-auto-newline -1)
  ;; Show current function name in status line.
  (which-function-mode t)
  ;; Enable some minor modes.
  (hs-minor-mode t)
  ;; Add keywords to cc mode
  (sec-unix-code-add-keywords)
  (setq c-electric-pound-behavior '(alignleft))
  (add-hook 'sec-newline-hook 'sec-auto-insert-comment-star-hook)
  (add-to-list 'c-cleanup-list 'comment-close-slash))

;; Common hook across all languages. It's run immediately before the language specific hook.
(add-hook 'c-initialization-hook 'sec-unix-code-init-hook)
(add-hook 'c-mode-common-hook 'sec-unix-code-common-hook)

(defun sec-kill-buffer-when-compile-success (process)
  "*Close buffer when compile success."
  (set-process-sentinel process
                        (lambda (proc state)
                          (when (string-match "finished" state)
                            (run-at-time 0.5 nil 'delete-windows-on (process-buffer proc))))))
(add-hook 'compilation-start-hook 'sec-kill-buffer-when-compile-success)

;;; ,----------
;;  / GDB preferences
;;  `--------------------
;;
(sec-require-maybe 'gdb-ui)

;; Open many windows mode for gdb.
(setq-default gdb-many-windows t)

(defun sec-kill-buffer-when-gdb-exit ()
  "*Close buffer automatically when gdb process exited."
  (let ((process (ignore-errors (get-buffer-process (current-buffer)))))
    (when process
      (set-process-sentinel process
                            (lambda (proc state)
			      (if (fboundp 'gud-sentinel)
				  (gud-sentinel proc state))
                              (when (string-match "\\(finished\\|exited\\)" state)
                                (run-at-time 0.5 nil 'kill-buffer-and-window)))))))
(add-hook 'gdb-mode-hook 'sec-kill-buffer-when-gdb-exit)

;;;; ,----------
;;  / GNU GLOBAL
;;  `--------------------
;;
;; Use absolute path style in `GTAGS SELECT MODE'.
(sec-require-maybe 'gtags)
(add-hook 'gtags-mode-hook
	  (lambda ()
	    (define-key gtags-mode-map (kbd "M-.")   'gtags-find-tag)
	    (define-key gtags-mode-map (kbd "M-, s") 'gtags-find-symbol)
	    (define-key gtags-mode-map (kbd "M-, r") 'gtags-find-rtag)
	    (define-key gtags-mode-map (kbd "M-, f") 'gtags-find-file)
	    (define-key gtags-mode-map (kbd "M-, p") 'gtags-find-pattern)
	    (define-key gtags-mode-map (kbd "M-, k") 'sec-gtags-find-kernel-syscall)
	    (define-key gtags-mode-map (kbd "M-*")   'gtags-pop-stack)
	    (setq gtags-path-style 'absolute)
            (setq gtags-select-buffer-single t)))

(defun sec-gtags-update ()
  "*Update the gtags file for current project"
  (interactive)
  (shell-command "global -vu"))

(dolist (hook sec-code-common-hooks)
  (add-hook hook (lambda () (gtags-mode t))))

(defadvice gtags-select-mode (after hl-line-advice activate)
  "*Enable HL-LINE mode in gtags-select-mode."
  (hl-line-mode 1))

(defun sec-gtags-find-kernel-syscall ()
  "*Find linux kernel system call quickly.
However, you can use `gtags-find-pattern' with regexp `^SYSCALL_DEFINE[0-6]*\(XXX.*\)$' to find the
syscall which defined with `SYSCALL_DEFINE' family macro, but this is very slow.
In this function, we use a efficiency way to do this job:
  -- 1. find the define of all the `SYSCALL_DEFINE' family macro, and put them in a buffer, this only
        waste little time.
  -- 2. kill the lines which not match our regexp."
  (interactive)
  (let (tagname prompt input)
    ;; Get the tagname we want to find.
    (setq tagname (gtags-current-token))
    (if tagname
	(setq prompt (concat "Find syscall: (default " tagname ") "))
      (setq prompt "Find syscall: "))
    (setq input (completing-read prompt 'gtags-completing-gsyms
				 nil nil nil gtags-history-list))
    (if (not (equal "" input)) (setq tagname input))
    (gtags-push-context)
    ;; Find begin.
    (let (option save prefix buffer lines)
      (setq save (current-buffer))
      ;; Use always ctags-x format.
      (setq option "-x")
      (setq prefix "(SYSCALL)")
      ;; Load tag
      (if (and (boundp 'gtags-select-buffer-single)
	       gtags-select-buffer-single)
	  (progn
	    ;; Delete "*GTAGS SELECT*" buffer info from gtags-buffer-stack and gtags-point-stack.
	    (let (now-gtags-buffer-stack now-buffer now-gtags-point-stack now-point)
	      (setq now-gtags-buffer-stack (reverse gtags-buffer-stack))
	      (setq now-gtags-point-stack (reverse gtags-point-stack))
	      (setq gtags-buffer-stack nil)
	      (setq gtags-point-stack nil)
	      (while now-gtags-buffer-stack
		(setq now-buffer (car now-gtags-buffer-stack))
		(setq now-point (car now-gtags-point-stack))
		(if (and (buffer-name now-buffer) (not (string-match "*GTAGS SELECT*" (buffer-name now-buffer))))
		    (progn
		      (setq gtags-buffer-stack (cons now-buffer gtags-buffer-stack))
		      (setq gtags-point-stack (cons now-point gtags-point-stack))))
		(setq now-gtags-buffer-stack (cdr now-gtags-buffer-stack))
		(setq now-gtags-point-stack (cdr now-gtags-point-stack))))
	    ;; Kill "*GTAGS SELECT*" buffer.
	    (let (now-buffer-list now-buffer)
	      (setq now-buffer-list (buffer-list))
	      (while now-buffer-list
		(setq now-buffer (car now-buffer-list))
		(if (string-match "*GTAGS SELECT*" (buffer-name now-buffer))
		    (kill-buffer now-buffer))
		(setq now-buffer-list (cdr now-buffer-list))))))
      ;; Select "*GTAGS SELECT*" buffer.
      (setq buffer (generate-new-buffer (generate-new-buffer-name (concat "*GTAGS SELECT* " prefix tagname))))
      (set-buffer buffer)
      ;; Path style is defined in gtags-path-style:
      ;; - root     : relative from the root of the project (Default)
      ;; - relative : relative from the current directory
      ;; - absolute : absolute (relative from the system root directory)
      (cond
       ((equal gtags-path-style 'absolute)
	(setq option (concat option "a")))
       ((equal gtags-path-style 'root)
	(let (rootdir)
	  (if gtags-rootdir
	      (setq root-dir gtags-rootdir)
	    (setq rootdir (gtags-get-rootpath)))
	  (if rootdir (cd rootdir)))))
      (message "Searching %s ..." tagname)
      (if (not (= 0 (call-process "global" nil t nil option "SYSCALL_DEFINE[0-6]*")))
	  ;; Some error occured.
	  (progn (message (buffer-substring (point-min)(1- (point-max))))
		 (gtags-pop-context))
	;; Call process success.
	(keep-lines (concat "SYSCALL_DEFINE[0-6]*\(" tagname "[,)]") (point-min) (point-max))
	(goto-char (point-min))
	(setq lines (count-lines (point-min) (point-max)))
	(cond
	 ((= 0 lines)
	  (message "%s: syscall not found" tagname)
	  (gtags-pop-context)
	  (kill-buffer buffer)
	  (set-buffer save))
	 ((= 1 lines)
	  (message "Searching %s ... Done" tagname)
	  (gtags-select-it t))
	 (t
	  (switch-to-buffer buffer)
	  (gtags-select-mode)))))))

;;;; ,----------
;;  / CEDET
;;  `--------------------
;;
;; (the Collection of Emacs Development Tools)
;; This plugin is already interated info emacs from version 23.2.
;;
(defconst sec-use-inner-cedet nil
  "*Whether use the inner cedet of emacs.")

;; Choose features of semantic to enable
(setq-default semantic-default-submodes
	      '(global-semantic-idle-scheduler-mode
		global-semanticdb-minor-mode
		))

(if sec-use-inner-cedet
    (progn
      (semantic-mode t))
  (progn
    ;; Enable sematic feartures
    (sec-add-sub-to-load-path (concat sec-rt-site-lisp-path "cedet-1.0pre7/"))
    (sec-require-maybe 'cedet)
    ;; Enable some semantic minor mode
    (dolist (mode semantic-default-submodes)
      (funcall mode 1))))

;; This mode is not contained by `semantic-default-submodes', so enable it here.
(global-semantic-show-parser-state-mode 1)

;; Some misc config.
(setq-default semantic-idle-scheduler-idle-time 1
	      semantic-complete-inline-analyzer-displayor-class 'semantic-displayor-ghost)

;; Add system include directories
(let* ((user-includes
	(list "../include" "../../include"))
       (system-includes
	(list "/usr/include" "/usr/local/include"))
       (include-dirs user-includes))
  (when (or (eq system-type "gnu")
	    (eq system-type "gnu/linux")
	    (eq system-type "gnu/kfreebsd"))
    (setq include-dirs (append include-dirs system-includes)))
  (dolist (dir include-dirs)
    (semantic-add-system-include dir)))

;; Semantic cache path configuration, even if this value can't be found in `C-h v' :)
(let ((semantic-cache (concat sec-emacs-cache-path "semantic.cache/")))
  (unless (file-exists-p semantic-cache)
    (make-directory semantic-cache t))
  (setq semanticdb-default-save-directory semantic-cache))

;;;; ,----------
;;  / ECB
;;  `--------------------
;;
;; (Emacs Code Browser)
;; This plugin works only when `CEDET' has been installed.
;;
(defun sec-create-unix-ecb-layout ()
  "*Create personal ecb layout."
  (interactive)
  (ecb-layout-define "sec-unix-ecb-layout" right
    "This function creates the following layout:
                     -------------------------------------------------------
                     |                                      |              |
                     |                                      |              |
                     |                                      |              |
                     |                                      |  Directories |
                     |                                      |              |
                     |                                      |              |
                     |                                      |              |
                     |             Edit                     |--------------|
                     |                                      |              |
                     |                                      |              |
                     |                                      |              |
                     |                                      |  Methods     |
                     |                                      |              |
                     |                                      |              |
                     |                                      |              |
                     -------------------------------------------------------
                     |                                                     |
                     |                    Compilation                      |
                     |                                                     |
                     -------------------------------------------------------

                     If you have not set a compilation-window in `ecb-compile-window-height' then
                     the layout contains no persistent compilation window and the other windows get a
                     little more place."
    ;; (ecb-set-directories-buffer)
    ;; (ecb-split-ver 0.5)
    (ecb-set-methods-buffer)
    (select-window (previous-window (selected-window) 0) 0))
  (setq ecb-layout-name "sec-unix-ecb-layout"))

;; Enable ecb and create layout.
(sec-require-maybe 'ecb)
(sec-create-unix-ecb-layout)

(defun sec-toggle-ecb ()
  "*Toggle ecb active/deactive."
  (interactive)
  (when (boundp 'ecb-minor-mode)
    (if ecb-minor-mode
	(ecb-deactivate)
      (ecb-activate))))

;;;; ,----------
;;  / Custom Settings
;;  `--------------------
;;
(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(ecb-layout-window-sizes nil)
 '(ecb-options-version "2.40")
 '(ecb-tip-of-the-day nil)
 '(ecb-windows-width 0.20)
 '(ecb-show-sources-in-directories-buffer 'always)
 '(ecb-auto-update-methods-after-save t)
 '(ecb-auto-expand-tag-tree 'expand-spec)
 '(ecb-highlight-tag-with-point 'highlight-scroll)
 '(ecb-highlight-tag-with-point-delay 0.20)
 '(ecb-auto-expand-tag-tree-collapse-other 'only-if-on-tag)
 '(ecb-methods-switch-off-auto-expand nil)
 '(ecb-type-tag-expansion nil)
 '(ecb-methods-nodes-collapse-spec nil)
 '(ecb-methods-nodes-expand-spec nil)
 ;; How to show tags in the methods buffer first time after find-file.
 ;; This functionality is set on a major-mode base, i.e. for every major-mode a
 ;; different setting can be used. The value of this option is a list of
 ;; cons-cells:
 '(ecb-show-tags '((default
		     (include collapsed nil)
		     (parent collapsed nil)
		     (type expanded nil)
		     (variable expanded access)
		     (function expanded access)
		     (label hidden nil)
		     (t collapsed nil))))
 ;; This variable is potentially risky when used as a file local variable.
 '(ecb-tag-display-function '((default . ecb-format-tag-name)))
 )

;;;; ,----------
;;  / Yasnippet
;;  `--------------------
;;
(sec-require-maybe 'yasnippet)
(yas/initialize)
(yas/load-directory (concat sec-rt-root-path "snippets"))

;; Indent behavior when insert snippet.
(make-variable-buffer-local 'yas/indent-line)
(setq-default yas/indent-line 'auto)

(dolist (hook sec-code-common-hooks)
  (add-hook hook (lambda () (yas/minor-mode t))))

;; Use `fixed' indent mode for `makefile-mode'.
(add-hook 'makefile-mode-hook
	  (lambda () (setq yas/indent-line 'fixed)))

;;;; ,----------
;;  / SLIME
;;  `--------------------
;;
;; Tell slime what lisp implementation to use.
(sec-require-maybe 'slime)
(setq inferior-lisp-program "sbcl")

;;;; ,----------
;;  / SAVE PLACE
;;  `--------------------
;;
;; When visit a file, point goes to the last place where it was when
;; previously visited the same file.
(sec-require-maybe 'saveplace)
(setq-default save-place t)

(let ((save-place-cache (concat sec-emacs-cache-path "save-place.cache/")))
  (unless (file-exists-p save-place-cache)
    (make-directory save-place-cache t))
  (setq-default save-place-file
		(concat save-place-cache "save-place")))

;;;; ,----------
;;  / Key-binding misc
;;  `--------------------
;;
;; Global key binding.
(global-set-key (kbd "RET")     'sec-smart-newline-and-indent)
(global-set-key (kbd "DEL")     'sec-smart-backspace)
(global-set-key (kbd "C-x C-o") 'ff-find-other-file)
(global-set-key (kbd "<f2>")    'sec-fetch-eshell)
(global-set-key (kbd "<f3>")    'sec-fetch-term)
(global-set-key (kbd "<f4>")    'calc)
(global-set-key (kbd "<f5>")    'compile)
(global-set-key (kbd "<f6>")    'gdb)
(global-set-key (kbd "<f7>")    'gdb-many-windows)
(global-set-key (kbd "<f8>")    'sec-toggle-ecb)
(global-set-key (kbd "<f9>")    'sec-reload-emacs-config)
(global-set-key (kbd "<f11>")   'sec-toggle-full-screen)
